#include "TcpConnection.hpp"
#include "EventLoop.hpp"
#include "Message.hpp"
#include <iostream>
using std::cout;
using std::endl;
using std::bind;

namespace wd{


TcpConnection::TcpConnection(int clientfd, EventLoop* eventloop)
:_sock(clientfd)
,_sockio(clientfd)
,_localAddr(getlocalAddr())
,_peerAddr(getpeerAddr())
,_eventloop(eventloop)
{
}

#if 0
string TcpConnection::receive(){
    char buff[65535];
    int ret = _sockio.readline(buff,sizeof(buff));
    return string(buff,ret);    
}
#endif

int TcpConnection::receive(Packet & packet){
    int ret = _sockio.readPacket(packet);
    /* printf("in TcpConnection::receive %d bytes\n",ret); */
    return ret;
}


void TcpConnection::send(const string & msg){
    int ret = _sockio.sendn(msg.c_str(),msg.size());
    printf(">>> send %d bytes.\n", ret);
}
    
bool TcpConnection::isClose() const{
    char buff[100] = {0};
    int ret = _sockio.recvPeek(buff,100);
    return ret == 0;
}

struct sockaddr_in TcpConnection::getlocalAddr(){
    struct sockaddr_in addr;
    memset(&addr,0,sizeof(addr));
    socklen_t len = sizeof(addr);
    int ret = getsockname(_sock.fd(),(struct sockaddr*)&addr,&len);
    if(ret < 0){
        perror("getsockname");
    }
    return addr;
}

struct sockaddr_in TcpConnection::getpeerAddr(){
    struct sockaddr_in addr;
    memset(&addr,0,sizeof(addr));
    socklen_t len = sizeof(addr);
    int ret = getpeername(_sock.fd(),(struct sockaddr*)&addr,&len);
    if(ret < 0){
        perror("getpeername");
    }
    return addr;

}
    
//让send功能在主线程中执行
void TcpConnection::sendInLoop(const string & msg){
    if(_eventloop){
        _eventloop->addFunctor(bind(&TcpConnection::send,this,msg));
    }
}

void TcpConnection::sendInLoop(const TLV & tlv){
    int tlvlen = 8 + tlv.length;
    //将TLV格式的数据整个变成string类型
    string msg;
    msg.assign((const char*)&tlv,tlvlen);
    sendInLoop(msg);
}
void TcpConnection::sendInLoop(const TLV2 & tlv){
    string msg;
    msg.assign((const char*)&tlv,8);
    printf("1 send TLV2 msg's sz: %ld\n", msg.size());
    msg.append(tlv.data,tlv.length);
    printf("2 send TLV2 msg's sz: %ld\n", msg.size());
    sendInLoop(msg);
}


void TcpConnection::set_pwdp(string pwdp){
    _pwdp = pwdp;
}

string TcpConnection::get_pwdp(){
    return _pwdp;
}

void TcpConnection::set_username(string username){
    _username = username;
}
string TcpConnection::get_username(){
    return _username;
}
void TcpConnection::set_salt(string salt){
    _salt = salt;
}
string TcpConnection::get_salt(){
    return _salt;
}
    
bool TcpConnection::mysql_writeQuery(const string & sql){
    return _eventloop->mysql_writeQuery(sql);
}
    
vector<vector<string>> TcpConnection::mysql_readQuery(const string & sql){
    return _eventloop->mysql_readQuery(sql);
}

}

